home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 43
/
Amiga Format CD43 (1999)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1999-09].iso
/
-serious-
/
wb
/
flynn
/
source
/
flynnapp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-06-15
|
12KB
|
631 lines
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <intuition/intuition.h>
#include <dos/dos.h>
#include <libraries/screennotify.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <proto/intuition.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/guigfx.h>
#include <proto/graphics.h>
#include <proto/screennotify.h>
#include <proto/icon.h>
#include "flynnapp.h"
#include "global.h"
#include "defs.h"
#include "subtask.h"
#include "flynnpic.h"
#include "tools.h"
void inputloop (struct FlynnApp *flynnapp);
struct FlynnApp *CreateFlynnApp(void);
void DeleteFlynnApp(struct FlynnApp *app);
void ReadConfig(struct FlynnApp *app);
void WriteConfig(struct FlynnApp *app);
int flynn_idle[] = {0,0,5,0,0,10,0,0,0,0,5,5,0,0,0,5,0,0,0,10,0,0,10,10,0,-1};
int flynn_hate[] = {15, -1};
int flynn_evil[] = {20, -1};
int flynn_dead[] = {25, -1};
int flynn_god[] = {26, -1};
int *flynn_anim[] = {flynn_idle, flynn_evil, flynn_hate, flynn_dead, flynn_god, NULL};
LONG __saveds idlefunc(APTR subtask, BYTE abortsignal)
{
struct idledata *data;
ULONG abortsignals = 1 << abortsignal, signals;
struct Task *mytask = FindTask(NULL);
data = ObtainData(subtask);
data->count = 0;
do
{
LONG newpri = ((drand48() * 2.0 - 1.0) * (drand48() * 2.0 - 1.0)) * 7.0;
SetTaskPri(mytask, newpri);
Delay(4);
data->count++;
signals = SetSignal(0, abortsignals);
} while (!(signals & abortsignals));
ReleaseData(subtask);
return 0;
}
static int evilcount = 0;
static int updateflynn(struct FlynnApp *app)
{
int index;
static int lastcount = 0;
float oldhealth, newhealth;
static int hatecount = 0;
oldhealth = app->flynnhealth;
app->flynnhealth -= 0.20;
app->flynnhealth += (app->idledata.count - lastcount) / 21.0;
if (app->flynnhealth < 0.01) app->flynnhealth = 0.01;
if (app->flynnhealth > 1.0) app->flynnhealth = 1.0;
newhealth = app->flynnhealth;
lastcount = app->idledata.count;
if (newhealth - oldhealth < -0.20)
{
app->flynnanimptr = NULL;
app->flynnmode = FLYNN_HATE;
hatecount = 6;
}
if (app->flynnmode == FLYNN_HATE)
{
if (--hatecount <= 0)
{
app->flynnanimptr = NULL;
app->flynnmode = FLYNN_IDLE;
}
}
if (app->flynnmode == FLYNN_EVIL)
{
if (--evilcount <= 0)
{
app->flynnanimptr = NULL;
app->flynnmode = FLYNN_IDLE;
}
}
if (app->flynnanimptr)
{
app->flynnanimptr++;
if (*app->flynnanimptr == -1)
{
app->flynnanimptr = NULL;
}
}
if (app->flynnanimptr == NULL)
{
app->flynnanimptr = flynn_anim[app->flynnmode];
}
index = *app->flynnanimptr + (1.0 - app->flynnhealth) * 5;
return index;
}
void main(void)
{
if (InitGlobal())
{
struct FlynnApp *app;
if (app = CreateFlynnApp())
{
int oldpri = SetTaskPri(FindTask(NULL), 2);
srand(time(NULL));
inputloop(app);
SetTaskPri(FindTask(NULL), oldpri);
DeleteFlynnApp(app);
}
CloseGlobal();
}
}
void inputloop (struct FlynnApp *app)
{
BOOL finish = FALSE;
ULONG signals;
ULONG idcmpsignals;
ULONG scrnotifysignals = 0;
struct IntuiMessage *imsg;
struct IntuiMessage myimsg;
int last_index = -1, new_index;
BOOL refresh = TRUE;
int writeconfig = 0;
APTR dh = NULL;
if (ScreenNotifyBase && app->scrmsgport && app->scrnotifyhandle)
{
scrnotifysignals = (1 << app->scrmsgport->mp_SigBit);
}
do
{
new_index = updateflynn(app);
if (!dh && app->window)
{
ClearWindow(app->window);
dh = ObtainDrawHandle(app->psm, app->window->window->RPort,
app->window->screen->ViewPort.ColorMap,
GGFX_DitherMode, DITHERMODE_NONE,
GGFX_AutoDither, FALSE, TAG_DONE);
}
if (dh && app->window)
{
if (new_index != last_index || refresh)
{
DrawPicture(dh, app->flynnpicture,
app->window->innerleft + BORDERX,
app->window->innertop + BORDERY,
GGFX_SourceWidth, FLYNNWIDTH, GGFX_SourceX, 0,
GGFX_SourceHeight, FLYNNHEIGHT,
GGFX_SourceY, new_index * FLYNNHEIGHT,
GGFX_DestWidth, app->window->innerwidth - BORDERX*2,
GGFX_DestHeight, app->window->innerheight - BORDERY*2,
TAG_DONE);
last_index = new_index;
}
}
if (refresh)
{
refresh = FALSE;
}
else
{
Delay( (ULONG)((drand48() - 0.5) * 7.0 + 25.0));
}
idcmpsignals = app->window ? app->window->idcmpSignal : 0;
signals = SetSignal(0, SIGBREAKF_CTRL_C | idcmpsignals | scrnotifysignals);
if ((signals & idcmpsignals) && app->window)
{
while (imsg = (struct IntuiMessage *) GetMsg(app->window->window->UserPort))
{
memcpy(&myimsg, imsg, sizeof(struct IntuiMessage));
ReplyMsg((struct Message *) imsg);
switch (myimsg.Class)
{
case ACTIVEWINDOW:
case INACTIVEWINDOW:
writeconfig = 10;
break;
case MOUSEBUTTONS:
// printf("icode %ld\n", myimsg.Code);
if (myimsg.Code == 233)
{
app->flynnanimptr = NULL;
app->flynnmode = FLYNN_EVIL;
evilcount = 3;
}
// else
// {
// app->flynnhealth -= 0.2;
// }
break;
case NEWSIZE:
ClearWindow(app->window);
UpdateWindowParameters(app->window);
app->window->sizegadget.LeftEdge = app->window->window->Width-SIZESIZE;
app->window->sizegadget.TopEdge = app->window->window->Height-SIZESIZE;
app->window->draggadget.Width = app->window->window->Width;
app->window->draggadget.Height = app->window->window->Height;
refresh = TRUE;
writeconfig = 10;
break;
case VANILLAKEY:
switch (myimsg.Code)
{
case 27:
finish = TRUE;
break;
}
}
}
}
if (signals & scrnotifysignals)
{
struct ScreenNotifyMessage *snm;
while (snm = (struct ScreenNotifyMessage *) GetMsg(app->scrmsgport))
{
if (snm->snm_Type == SCREENNOTIFY_TYPE_WORKBENCH)
{
if (snm->snm_Value == FALSE)
{
if (app->window)
{
app->winx = app->window->window->LeftEdge;
app->winy = app->window->window->TopEdge;
app->winwidth = app->window->window->Width;
app->winheight = app->window->window->Height;
ReleaseDrawHandle(dh);
dh = NULL;
DeleteMVWindow(app->window);
app->window = NULL;
}
}
else
{
if (!app->window)
{
if (!(app->window = CreateMVWindow(app->winx, app->winy, app->winwidth, app->winheight)))
{
finish = TRUE;
}
}
}
}
ReplyMsg((struct Message *) snm);
}
}
if (writeconfig)
{
if (--writeconfig == 0)
{
WriteConfig(app);
}
}
if (signals & SIGBREAKF_CTRL_C)
{
finish = TRUE;
}
} while (!finish);
SetRast(app->window->window->RPort, app->window->backpen);
ReleaseDrawHandle(dh);
}
struct FlynnApp *CreateFlynnApp(void)
{
struct FlynnApp *app;
BOOL success = FALSE;
if (app = Malloclear(sizeof(struct FlynnApp)))
{
app->winx = -1;
app->winy = -1;
app->winwidth = APPWIDTH;
app->winheight = APPHEIGHT;
if (_WBenchMsg)
{
if (NameFromLock(GetProgramDir(), app->filenamebuffer, MAXNAMELEN))
{
if (AddPart(app->filenamebuffer, _WBenchMsg->sm_ArgList[0].wa_Name, MAXNAMELEN))
{
app->progname = StrDup(app->filenamebuffer);
}
}
}
else
{
if (GetProgramName(app->filenamebuffer, MAXNAMELEN))
{
char *s;
if (s = StrDup(app->filenamebuffer))
{
if (NameFromLock(GetProgramDir(), app->filenamebuffer, MAXNAMELEN))
{
if (AddPart(app->filenamebuffer, s, MAXNAMELEN))
{
app->progname = StrDup(app->filenamebuffer);
}
}
Free(s);
}
}
}
ReadConfig(app);
if (app->subtask = SubTask(idlefunc, &app->idledata, 1000, 0, "flynn idletask (%x)", NULL, FALSE))
{
app->window = CreateMVWindow(app->winx, app->winy, app->winwidth, app->winheight);
// app->flynnpicture = LoadPicture("flynn.picture", TAG_DONE);
app->flynnpicture = MakePicture(flynndata, 24, 864,
GGFX_NumColors, 256, GGFX_Palette, flynnpalette, TAG_DONE);
app->psm = CreatePenShareMap(TAG_DONE);
app->flynnhealth = 1.0;
app->flynnmode = FLYNN_IDLE;
app->flynnanimptr = NULL;
if (app->window && app->flynnpicture && app->psm)
{
if (ScreenNotifyBase)
{
if (app->scrmsgport = CreateMsgPort())
{
app->scrnotifyhandle = AddWorkbenchClient(app->scrmsgport, 0);
}
}
GetPictureAttrs(app->flynnpicture,
PICATTR_Width, &app->flynnwidth,
PICATTR_Height, &app->flynnheight,
TAG_DONE);
AddPicture(app->psm, app->flynnpicture, TAG_DONE);
success = TRUE;
}
}
}
if (!success)
{
DeleteFlynnApp(app);
app = NULL;
}
return app;
}
void DeleteFlynnApp(struct FlynnApp *app)
{
if (app)
{
if (app->window)
{
WriteConfig(app);
}
Free(app->progname);
if (ScreenNotifyBase)
{
if (app->scrnotifyhandle)
{
while (!RemWorkbenchClient(app->scrnotifyhandle))
{
Delay(10);
}
}
DeleteMsgPort(app->scrmsgport);
}
if (app->subtask)
{
AbortSubTask(app->subtask);
CloseSubTask(app->subtask);
}
DeletePenShareMap(app->psm);
DeletePicture(app->flynnpicture);
DeleteMVWindow(app->window);
Free(app);
}
}
void ReadConfig(struct FlynnApp *app)
{
if (app->progname)
{
struct DiskObject *dobj;
if (dobj = GetDiskObject(app->progname))
{
char **tt = dobj->do_ToolTypes;
char *p;
if (p = FindToolType(tt, "WINLEFT"))
{
app->winx = atoi(p);
}
if (p = FindToolType(tt, "WINTOP"))
{
app->winy = atoi(p);
}
if (p = FindToolType(tt, "WINWIDTH"))
{
app->winwidth = atoi(p);
}
if (p = FindToolType(tt, "WINHEIGHT"))
{
app->winheight = atoi(p);
}
FreeDiskObject(dobj);
}
}
}
void SetTTEntry(struct List *ttlist, char *name, int value)
{
BOOL found = FALSE;
char buffer[100];
struct Node *node, *nextnode;
int len = strlen(name), dlen;
char *newstring, *disabled;
sprintf(buffer, "%s=%ld", name, value);
newstring = StrDup(buffer);
sprintf(buffer, "(%s", name);
disabled = StrDup(buffer);
if (newstring && disabled)
{
dlen = strlen(disabled);
node = ttlist->lh_Head;
while (nextnode = node->ln_Succ)
{
if (strncmp(name, node->ln_Name, len) == 0)
{
found = TRUE;
}
else if (strncmp(disabled, node->ln_Name, dlen) == 0)
{
found = TRUE;
}
if (found)
{
Free(node->ln_Name);
node->ln_Name = newstring;
newstring = NULL;
break;
}
node = nextnode;
}
if (!found)
{
struct Node *newnode;
if (newnode = CreateNode(newstring))
{
AddTail(ttlist, newnode);
}
}
}
Free(newstring);
Free(disabled);
}
void WriteConfig(struct FlynnApp *app)
{
if (app->progname && app->window)
{
struct DiskObject *dobj;
dobj = GetDiskObject(app->progname);
if (!dobj)
{
dobj = GetDefDiskObject(WBTOOL);
}
if (dobj)
{
struct List *ttlist;
if (ttlist = CreateListFromArray(dobj->do_ToolTypes))
{
char **newtt;
SetTTEntry(ttlist, "WINLEFT", app->window->window->LeftEdge);
SetTTEntry(ttlist, "WINTOP", app->window->window->TopEdge);
SetTTEntry(ttlist, "WINWIDTH", app->window->window->Width);
SetTTEntry(ttlist, "WINHEIGHT", app->window->window->Height);
if (newtt = CreateStringArrayFromList(ttlist))
{
dobj->do_ToolTypes = newtt;
PutDiskObject(app->progname, dobj);
FreeStringArray(newtt);
}
DeleteList(ttlist);
}
FreeDiskObject(dobj);
}
}
}